Unit BControllerUnit;

{$mode objfpc}{$H+}
{$interfaces corba}

Interface

Uses
  Classes, SysUtils, BCommonUnit, BListsUnit, BObjectUnit, BTreeObjectUnit;

Type IControllerInterface = Interface
  Function DeleteObject(Const aID: Integer): Boolean;
  Procedure Commit(Var aErrorInfo: BErrorInfoRec);
End;

Type

{ BControllerGeneric }

Generic BControllerGeneric<BManagedClass, BManagerClass> = Class (IControllerInterface)
  Type BManagedList = Specialize BList<BManagedClass>;
  Type BManagedThreadList = Specialize BThreadList<BManagedClass>;
  Protected
    bBurnManager: Boolean;
    bManager: BManagerClass;
    Function GetJSON(Const aObject: BManagedClass): String; Virtual;
    Function GetNodeJSON(Const aObject: BManagedClass;
      Const aChecked: Boolean = FALSE;
      Const aState: Boolean = FALSE): String; Virtual;
  Public
    Function PlainSendToTree(Const aList: BManagedList): String;
    Function PlainSendToGrid(Const aList: BManagedList): String;

    Function GetPlainJSON: String;
    Function GetFormattedJSON(Const aCallback: String = '';
      Const aWithCount: Boolean = FALSE;
      Const aStart: Integer = 0; aLimit: Integer = -1): String;
    Function GetTreeJSON(Const aCheckedList: BManagedThreadList): String;


    Function GetSpecificJSON(Const aSpecificList: BManagedList;
      Const aExcepted: Boolean = FALSE;
      Const aCheckedList: BManagedThreadList = nil): String;

    Function DeleteObject(Const aID: Integer): Boolean;

    Procedure Commit(Var aErrorInfo: BErrorInfoRec); Virtual;
    Procedure Rollback;

    Constructor Build(Const aManager: BManagerClass); Virtual;


    Destructor Burn; Virtual;
End;

Implementation

Function BControllerGeneric.GetJSON(Const aObject: BManagedClass): String;
Begin
  Result := IntToStr(aObject.ID);
End;

Function BControllerGeneric.GetNodeJSON(Const aObject: BManagedClass;
  Const aChecked: Boolean; Const aState: Boolean): String;
Begin
  Result := GetJSON(aObject);
  If aChecked Then
    Result += BoolToStr(aState);
End;

Function BControllerGeneric.PlainSendToTree(Const aList: BManagedList): String;
Var
  i: Integer;
Begin
  For i := 0 To aList.Count - 1 Do
    AppendCommaString(Result, '{%s}', [GetNodeJSON(aList[i])]);
  Result := Format('[%s]', [Result]);
End;

Function BControllerGeneric.PlainSendToGrid(Const aList: BManagedList): String;
Var
  i: Integer;
Begin
  For i := 0 To aList.Count - 1 Do
    AppendCommaString(Result, '{%s}', [GetJSON(aList[i])]);
  Result := Format('({objects:[%s]});', [Result])
End;

Function BControllerGeneric.GetPlainJSON: String;
Var
  i: Integer;
  aList: BManagedList;
Begin
  Result := '';
  aList := BManagedList(bManager.Committed.LockList);
  For i := 0 To aList.Count - 1 Do
    If Not(aList.GetAt(i).Deleted) Then
      AppendCommaString(Result, Format('{%s}', [GetJSON(aList.GetAt(i))]));
  bManager.Committed.UnlockList;
End;

Function BControllerGeneric.GetFormattedJSON(Const aCallback: String;
  Const aWithCount: Boolean;
  Const aStart: Integer; aLimit: Integer): String;
Var
  i: Integer;
  aList: BManagedList;
  aCountString: String;
Begin
  Result := '';
  aList := BManagedList(bManager.Committed.LockList);
  If aLimit = -1 Then aLimit := aList.Count - 1;
  For i := aStart To aStart + aLimit Do
    If Not(aList.GetAt(i).Deleted) Then
      AppendCommaString(Result, Format('{%s}', [GetJSON(aList.GetAt(i))]));
  aCountString := '';
  If aWithCount Then
    aCountString := Format('"objectsCount":"%d",', [aLimit]);
  Result := Format('%s({%s"objects":[%s]});', [aCallback,aCountString, Result]);
  bManager.Committed.UnlockList;
End;

Function BControllerGeneric.GetTreeJSON(
  Const aCheckedList: BManagedThreadList): String;
Var
  i: Integer;
  aBuffer: String;
  aList, aChecked: BManagedList;
Begin
  Result := '';
  aList := BManagedList(bManager.Committed.LockList);
  If Not(aCheckedList = nil) Then aChecked := aCheckedList.LockList;
  For i := 0 To aList.Count - 1 Do
    If Not(aList.GetAt(i).Deleted) Then
      Begin
        aBuffer := GetNodeJSON(aList.GetAt(i));
        If Not(aChecked = nil) Then
          If aChecked.Present(aList.GetAt(i)) Then aBuffer += ',checked:true'
          Else aBuffer += ',checked:false';
        AppendCommaString(Result, Format('{%s}', [aBuffer]));
      End;
  Result := Format('[%s]', [Result]);
  bManager.Committed.UnlockList;
End;

Function BControllerGeneric.GetSpecificJSON(Const aSpecificList: BManagedList;
  Const aExcepted: Boolean; Const aCheckedList: BManagedThreadList): String;
Begin
  Result := '';
  If aExcepted And (aSpecificList = nil) And (aCheckedList = nil) Then
    Result += '';
End;

Function BControllerGeneric.DeleteObject(Const aID: Integer): Boolean;
Var
  aObject: BManagedClass;
Begin
  Result := FALSE;
  aObject := bManager.GetObject(aID);
  If Not(aObject = nil) Then
    Begin
      bManager.DeleteObject(aObject);
      Result := TRUE;
    End;
End;

Procedure BControllerGeneric.Commit(Var aErrorInfo: BErrorInfoRec);
Begin
  If Not(aErrorInfo.Code = 0) Then Exit;
  Try
    bManager.Commit;
  Except On E: BExceptionClass Do
    aErrorInfo := BuildErrorInfo(E.Code, E.Message);
  End;
End;

Procedure BControllerGeneric.Rollback;
Begin
  bManager.Rollback;
End;

Constructor BControllerGeneric.Build(Const aManager: BManagerClass);
Begin
  bBurnManager := FALSE;
  bManager := aManager;
End;

Destructor BControllerGeneric.Burn;
Begin
  If bBurnManager Then bManager.Burn;
End;

End.

